package com.itmk.web.sys_user.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.code.kaptcha.Producer;
import com.itmk.jwt.JwtUtils;
import com.itmk.utils.Result;
import com.itmk.web.sys_menu.entity.AssignTreeParm;
import com.itmk.web.sys_menu.entity.AssignTreeVo;
import com.itmk.web.sys_menu.entity.SysMenu;
import com.itmk.web.sys_menu.service.SysMenuService;
import com.itmk.web.sys_user.entity.*;
import com.itmk.web.sys_user.service.SysUserService;
import com.itmk.web.sys_user_role.entity.SysUserRole;
import com.itmk.web.sys_user_role.service.SysUserRoleSrevice;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping("/api/user")
@RestController
public class SysUserController {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysUserRoleSrevice sysUserRoleSrevice;

    @Resource
    private Producer producer;

    @Resource
    private JwtUtils jwtUtils;

    @Resource
    private SysMenuService sysMenuService;


    //新增
    @PostMapping
    public Result<Object> add(@RequestBody SysUser sysUser) {
        sysUser.setCreateTime(new Date());
        sysUserService.saveUser(sysUser);
        return Result.ok().message("新增用户成功");

    }

    //编辑
    @PutMapping
    public Result<Object> update(@RequestBody SysUser sysUser) {
        sysUser.setUpdateTime(new Date());
        sysUserService.updateUser(sysUser);
        return Result.ok().message("编辑用户成功");
    }

    //删除
    @DeleteMapping("/{userId}")
    public Result<Object> deletebyId(@RequestParam("userId") Long userId) {
        sysUserService.deleteUser(userId);
        return Result.ok().message("删除用户成功");
    }

    //查询
    @GetMapping("/getList")
    public Result getList(UserParm parm) {
        IPage<SysUser> page = new Page<>(parm.getCurrentPage(), parm.getPageSize());
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        //如果有内容就构造到条件里
        if (StringUtils.isNotEmpty(parm.getNickName())) {
            queryWrapper.lambda().like(SysUser::getNickName, parm.getNickName());
        }
        if (StringUtils.isNotEmpty(parm.getPhone())) {
            queryWrapper.lambda().eq(SysUser::getPhone, parm.getPhone());
        }
        queryWrapper.lambda().orderByDesc(SysUser::getCreateTime);
        IPage<SysUser> list = sysUserService.page(page, queryWrapper);
        return Result.ok(list).message("获取用户列表成功");
    }

    //根据用户id查询角色信息
    @GetMapping("/getRoleList")
    public Result getRoleListByUserId(Long userId) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserRole::getUserId, userId);
        List<SysUserRole> list = sysUserRoleSrevice.list(queryWrapper);
        //角色id集合
        List<Long> roleIds = new ArrayList<>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .forEach(item -> {
                    roleIds.add(item.getRoleId());
                });

        return Result.ok(roleIds).message("根据用户id查询角色信息成功");
    }

    //重置密码
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestBody SysUser sysUser) {
        System.out.println(sysUser);
        UpdateWrapper<SysUser> queryWrapper = new UpdateWrapper<>();
        queryWrapper.lambda().eq(SysUser::getUserId, sysUser.getUserId())
                .set(SysUser::getPassword, "666666");
        if (sysUserService.update(queryWrapper)) {
            return Result.ok().message("密码重置成功");
        }
        return Result.fail().message("密码重置失败");

    }
    //获取验证码方法
    @GetMapping("/getVerifyCode")
    public Result getVerifyCode(HttpServletRequest request){
        //获取session
        HttpSession session = request.getSession();
        //生成验证码
        String text = producer.createText();
        session.setAttribute("code", text);
        //生成图片返回Base64
        BufferedImage image = producer.createImage(text);
        ByteArrayOutputStream outputStream = null;
        try{
            outputStream = new ByteArrayOutputStream();
            ImageIO.write(image,"jpg",outputStream);
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encode(outputStream.toByteArray());
            String captchaBase64 = "data:image/png;base64,"+base64.replaceAll("\r\n", "");
            Result<Object> result = new Result<>();
            result.setCode(200);
            result.setMessage("生成验证码成功");
            result.setData(captchaBase64);
            return result;

        }catch(IOException e){
            e.printStackTrace();
        } finally {
            try {
                if(outputStream==null){
                    outputStream.close();
                }
            } catch (IOException e){
                e.printStackTrace();
            }
        }
        return null;

    }

    //用户登录
    @PostMapping("/login")
    public Result login(@RequestBody LoginParm loginParm, HttpServletRequest request){
        //通过session获取code验证码
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute("code");
        //获取前端传过来的code
        String parmCode = loginParm.getCode();
        if(StringUtils.isEmpty(code)){
            return Result.fail().message("验证码过期");
        }
        //传递过来的code和session里面的比较
        if(!code.equals(parmCode)){
            return Result.fail().message("验证码错误");
        }
        //查询用户信息
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername,loginParm.getUsername())
                .eq(SysUser::getPassword,loginParm.getPassword());
        SysUser user = sysUserService.getOne(queryWrapper);
        if(user==null){
            return Result.fail().message("用户名或密码错误");
        }
        //返回用户信息
        LoginVo vo = new LoginVo();
        vo.setNickName(user.getNickName());
        vo.setUserId(user.getUserId());
        //jwt生成token返回
        Map<String,String> map= new HashMap<>();
        map.put("userId",Long.toString(user.getUserId()));
        String token = jwtUtils.generateToken(map);
        vo.setToken(token);
        return Result.ok(vo).message("登录成功");
    }
    //查询菜单树
    @GetMapping("/getAssignTree")
    public Result getAssignTree(AssignTreeParm parm){
        AssignTreeVo assignTree = sysUserService.getAssignTree(parm);
        return Result.ok(assignTree).message("查询成功");
    }
    //修改密码
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody UpdatePasswordParm parm){
        SysUser user = sysUserService.getById(parm.getUserId());
        if(!parm.getOldPassword().equals(user.getPassword())){
            return Result.fail().message("原密码错误");
        }
        UpdateWrapper<SysUser> query = new UpdateWrapper<>();
        query.lambda().set(SysUser::getPassword,parm.getNewPassword())
                .eq(SysUser::getUserId,parm.getUserId());
        if(sysUserService.update(query)){
            return Result.ok().message("密码更新成功");
        }
        return Result.fail().message("密码更新失败");

    }
    //获取用户信息
    @GetMapping("/getUserInfo")
    public Result getUserInfo(Long userId){
        //根据id查询用户信息
        SysUser user = sysUserService.getById(userId);
        List<SysMenu> menuList = null;
        //判断是否超级管理员
        if(StringUtils.isNotEmpty(user.getIsAdmin())&& "1".equals(user.getIsAdmin())){
            menuList = sysMenuService.list();
        }else{
            menuList = sysMenuService.getMenuByUserId(user.getUserId());
        }
        //过滤出code字段且不为空
        List<String> collect = Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream().filter(item ->item !=null && StringUtils.isNotEmpty(item.getCode()))
                .map(SysMenu::getCode)
                .collect(Collectors.toList());

        UserInfo userInfo = new UserInfo();
        userInfo.setName(user.getNickName());
        userInfo.setUserId(user.getUserId());
        userInfo.setPermissions(collect.toArray());

        return Result.ok(userInfo).message("获取用户信息成功");



    }
}
